package com.ynet.middleground.riskmanage.utils;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import org.apache.commons.lang.StringUtils;

import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

/**
 * @author liwq
 * @description xml 转换工具
 * @date 2021/11/5 11:19
 */
public class XStreamUtil {

    // 将standalone="yes"用空格替换掉
    public static final String STAND_ALONE = " standalone=\"yes\"";

    /**
     * JavaBean装换成xml 默认编码GBK
     *
     * @param obj
     * @return
     */
    public static String converTomXml(Object obj) {
        String returnXml = converToXml(obj, "GBK");
        returnXml = returnXml.replace(STAND_ALONE, "");
        return returnXml;
    }

    /**
     * JavaBean装换成xml
     *
     * @param obj
     * @param encoding
     * @return
     */
    private static String converToXml(Object obj, String encoding) {
        String result = null;
        try {
            JAXBContext context = JAXBContext.newInstance(obj.getClass());
            Marshaller marshaller = context.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
            StringWriter writer = new StringWriter();
            marshaller.marshal(obj, writer);
            result = writer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * xml装换成JavaBean
     *
     * @param xml
     * @param c
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> T converyToJavaBean(String xml, Class<T> c) {
        T t = null;
        try {
            JAXBContext context = JAXBContext.newInstance(c);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            t = (T)unmarshaller.unmarshal(new StringReader(xml));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return t;
    }

    // 以下方法是XStream框架 xml和java bean 转化的方法

    /**
     * 将bean转换为xml @param obj 转换的bean @return bean转换为xml
     */
    public static String objectToXml(Object obj, String head) {
        XStream xStream = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));
        // xstream使用注解转换
        xStream.processAnnotations(obj.getClass());
        String xml = xStream.toXML(obj);
        String a[] = xml.split("\\n");
        ArrayList b = new ArrayList();
        for (int i = 0; i < a.length; i++) {
            if (i > 4) {
                b.add(a[i]);
            }
        }
        b.remove(b.size() - 1);
        b.add(0, "<INPUT>");
        b.add(b.size(), "</INPUT>");
        if (StringUtils.isNotBlank(head)) {
            b.add(0, "<" + head + ">");
            b.add(b.size(), "</" + head + ">");
        }
        b.add(0, "<?xml version=\"1.0\" encoding=\"GBK\"?>");
        return StringUtils.join(b, "");
    }

    /**
     * 将xml转换为bean @param<T> 泛型 @param xml 要转换为bean的xml @param cls bean对应的Class @return xml转换为bean
     */
    public static <T> T xmlToObject(String xml, Class<T> cls) {
        XStream xstream = new XStream(new DomDriver());
        // xstream使用注解转换
        xstream.processAnnotations(cls);
        return (T)xstream.fromXML(xml);
    }
}
